package org.stream.answerduel.service;

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.stream.answerduel.entity.User;
import org.stream.answerduel.repository.UserRepository;
import org.stream.answerduel.vo.*;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class MatchService {
    // Comparator<User> userComparator = (User a, User b)->
    // {
    // return a.getPriority() - b.getPriority();
    // };

    @Autowired
    MatchThread matchThread;

    @Autowired
    UserRepository userRepository;
    //public List<MatchingUser> matchQueue = new CopyOnWriteArrayList<MatchingUser>();
    //public List<Room> roomList = new CopyOnWriteArrayList<Room>();

    public MatchService() {
        //matchThread = new MatchThread();
        // matchThread.addQueue(new User());
    }

    //@Async
    public void startMatch(UserVo user) {
        MatchingUser matchingUser = new MatchingUser(user);
        matchThread.addQueue(matchingUser);
    }
    public void startMatch(MatchingUser mUser) {
        matchThread.addQueue(mUser);
    }

    public void startMatch(String wechat_id) throws NoSuchElementException {
        User user = userRepository.findByWechatID(wechat_id);
        MatchingUser matchingUser = new MatchingUser(user);
        matchThread.addQueue(matchingUser);
    }

    public void startMatch(Long id) throws NoSuchElementException {
        Optional<User> user = userRepository.findById(id);
        MatchingUser matchingUser = new MatchingUser(user.get());
        matchThread.addQueue(matchingUser);
    }

    public boolean cancelMatch(Long id){
        return matchThread.removeQueue(id);
    }

    public boolean isInQueue(long id){
        return matchThread.isInQueue(id);
    }

    public boolean isInGame(long id){
        return matchThread.isInGame(id);
    }

    public boolean isInAnyWaitingRoom(long id){
        return matchThread.isInAnyWaitingRoom(id);
    }

    public String createWaitingRoom(Long id){
        User user = userRepository.findById(id).get();
        UserVo userVo = new UserVo(user);
        return matchThread.createWaitingRoom(userVo);
    }

    public WaitingUser joinWaitingRoom(Long id, String roomID){
        User user = userRepository.findById(id).get();
        UserVo userVo = new UserVo(user);
        return matchThread.joinWaitingRoom(userVo,roomID);
    }

    public void exitWaitingRoom(Long id, String roomID){
        matchThread.exitWaitingRoom(id, roomID);
    }

    public void forceExitWaitingRoom(Long id){
        matchThread.forceExitWaitingRoom(id);
    }

//    public void forceExitRoom(Long id){
//        matchThread.forceExitRoom(id);
//    }

    public boolean isRoomExist(Long roomID){
        return matchThread.isRoomExist(roomID);
    }

    public boolean isWaitingRoomExist(String roomID){
        return matchThread.isWaitingRoomExist(roomID);
    }

    public boolean isUserInRoom(Long id,Long roomID){
        return matchThread.isUserInRoom(id, roomID);
    }

    public boolean isUserInWaitingRoom(Long id,String roomID){
        return matchThread.isUserInWaitingRoom(id, roomID);
    }

    public boolean isWaitingRoomFull(String roomID){
        return matchThread.isWaitingRoomFull(roomID);
    }

    public AnswerResultVo answer(Long id, Long roomID, int choice)
    {
        return matchThread.answer(id,roomID,choice);
    }

    public void ready(Long id, Long roomID)
    {
        matchThread.ready(id, roomID);
    }

    public void prepare(Long id, String roomID)
    {
        matchThread.prepare(id, roomID);
    }

    public void cancelPrepare(Long id, String roomID)
    {
        matchThread.cancelPrepare(id, roomID);
    }

    public Long findRoomIDByUser(Long id){
        return matchThread.findRoomIDByUser(id);
    }

    public ReconnectVo reconnect(Long id, Long roomID){
        return matchThread.reconnect(id, roomID);
    }
}
